#include <iostream>
#include <array>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <fstream>
using namespace std;

/**
 * 有个 memtest 程序使用 malloc 分配内存，但有几处未调用 free 释放它（即存在内存泄露问题），
 * 请写个程序将这几处未释放的内存大小信息输出。
 * 每行输出一个未释放的内存大小，
 * 样例：
 * 111
 * 123
*/


struct log_entry {
	long action;
	long ptr;
	long size;
};

int read_entries(const std::string& filename, std::vector<log_entry>& entries)
{
	std::ifstream infile(filename, ios::binary);
	if (!infile.is_open()) {
		return -1;
	}

	while (!infile.eof()) {
		log_entry entry;
		infile.read((char*)&entry, sizeof(entry));
		if (infile.eof())
			break;

		entries.push_back(entry);
	}

	return entries.size();
}

int main()
{
	// export LD_LIBRARY_PATH=.
	if (system("LD_PRELOAD=libmemhook.so ./memtest")) {
		cout << "Failed to run memtest." << endl;
		return -1;
	}

	vector<log_entry> entries;
	read_entries("memhook.log", entries);

	//cout << entries.size() << endl;

	map<long, long> ptr_size_map;
	for (auto entry : entries) {
		if (entry.action == 0) {
			//cout << "malloc " << entry.ptr << endl;
			ptr_size_map[entry.ptr] = entry.size;
		}
		else if (entry.action == 1) {
			//cout << "free " << entry.ptr << endl;
			auto it = ptr_size_map.find(entry.ptr);
			if (it == ptr_size_map.end()) {
				cout  << "uninitialized pointer freed!!! ptr=" << entry.ptr << endl;
			}
			else {
				ptr_size_map.erase(it);
			}
		}
		else {
			cout << "invalid log" << endl;
			return -1;
		}

	}

	for (auto mem : ptr_size_map) {
		cout << mem.second << endl;
	}

	return 0;
}



